﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;

using LowLevelGraphics.Histograms;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// 
    /// </summary>
    public class HistogramThreshold : BaseForeBackgroundColorFilter
    {
        protected Histogram m_Histogram = null;
        protected float m_nLowThreshold = 0.2f;
        protected float m_nHighThreshold = 0.3f;

        /// <summary>
        /// Initializes a new instance of the <see cref="HistogramThreshold"/> class.
        /// </summary>
        public HistogramThreshold()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HistogramThreshold"/> class.
        /// </summary>
        public HistogramThreshold(Histogram _histogram)
        {
        }

        /// <summary>
        /// Gets or sets the histogram.
        /// </summary>
        /// <value>The histogram.</value>
        public Histogram Histogram
        {
            get { return m_Histogram; }
            set 
            {
                m_Histogram = value;
            }
        }

        /// <summary>
        /// Gets or sets the low threshold.
        /// </summary>
        /// <value>The low threshold.</value>
        public float LowThreshold
        {
            get { return m_nLowThreshold; }
            set { m_nLowThreshold = value; }
        }

        /// <summary>
        /// Gets or sets the high threshold.
        /// </summary>
        /// <value>The high threshold.</value>
        public float HighThreshold
        {
            get { return m_nHighThreshold; }
            set { m_nHighThreshold = value; }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HistogramThreshold"/> class.
        /// </summary>
        /// <param name="_histogramThreshold">The _histogram threshold.</param>
        internal HistogramThreshold(HistogramThreshold _histogramThreshold)
        {
        }

        /// <summary>
        /// Execute this Filter
        /// A Debug Statement is written if a concrete Filter is called
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            m_Histogram = new Histogram(10, _bitmap);

            int x = 0;
            int y = 0;
            int nWidth = _bitmap.Width;
            int nHeight = _bitmap.Height;

            int nCount = 0;
            int nPixelCount = nHeight * nWidth;
            Color color = Color.Transparent;

            int nIndex = 0;

            float fMean = m_Histogram.FindMean();
            for (y = 0; y < nHeight; y++)
            {
                for (x = 0; x < nWidth; x++)
                {
                    Color pPixel = _bitmap[x, y];
                    //get the bin index for the current pixel colour
                    nIndex = m_Histogram.GetSingleBinIndex(m_Histogram.BinCount1,
                          m_Histogram.BinCount2, m_Histogram.BinCount3, pPixel);


                    float fTest = m_Histogram.Data[m_Histogram.GetSingleBinIndex(10, 10, 10, _bitmap[x, y])];
                    bool bForegroundColor = m_nLowThreshold <= fMean && fMean <= m_nHighThreshold;
                    _bitmap.SetPixel(x, y, bForegroundColor ? m_ColorForeground : m_ColorBackground);
                }
            }
            if (nCount == nPixelCount)
            {
                //if we got here, nothing has worked out. Error in program code, somewhere
                Debug.WriteLine(String.Format("{0} if we got here, nothing has worked out. Error in program code, somewhere", new StackFrame().GetMethod().Name));
            }
            return _bitmap;
        }

        /// <summary>
        /// This is used to clone a filter, each filter must implement it's own clone functionality
        /// </summary>
        /// <returns></returns>
        public override object Clone()
        {
            return new HistogramThreshold(this);
        }
    }
}
